//
//  MLKitManager.m
//  Pods
//
//  Created by molon on 15/6/30.
//
//

#import "MLKitManager.h"
#import <CommonCrypto/CommonDigest.h>  //md5 用到
#import <MobileCoreServices/MobileCoreServices.h>
#import <AVFoundation/AVFoundation.h>
#import "MLKit.h"

@interface MLKitSelectPictureTask : NSObject<UINavigationControllerDelegate, UIImagePickerControllerDelegate>

@property (nonatomic, assign) BOOL directReturnOriginalImage;
@property (nonatomic, assign) BOOL allowsEditing;
@property (nonatomic, assign) double maxCompressedImageSize;
@property (nonatomic, copy) void (^compressedImageBlock)(UIImage *image,NSData *compressionData,MLURL *url);

- (void)selectPictureWithSourceType:(UIImagePickerControllerSourceType)sourceType;

@end

@interface MLKitManager()<UIActionSheetDelegate>

@property (nonatomic, strong) NSMutableArray *selectPictureTasks;

@end

@implementation MLKitManager

+ (instancetype)manager
{
    static MLKitManager *_sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[[self class] alloc]init];
    });
    return _sharedInstance;
}

#pragma mark - select image
- (NSMutableArray *)selectPictureTasks
{
    if (!_selectPictureTasks) {
        _selectPictureTasks = [NSMutableArray new];
    }
    return _selectPictureTasks;
}

- (void)selectPictureWithSourceType:(UIImagePickerControllerSourceType)sourceType maxCompressedImageSize:(double)maxCompressedImageSize callback:(void (^)(UIImage *image,NSData *compressedData,MLURL *url))callback
{
    [self selectPictureWithSourceType:sourceType allowEditing:NO directReturnOriginalImage:NO maxCompressedImageSize:maxCompressedImageSize callback:callback];
}

- (void)selectPictureWithSourceType:(UIImagePickerControllerSourceType)sourceType allowEditing:(BOOL)allowEditing directReturnOriginalImage:(BOOL)directReturnOriginalImage maxCompressedImageSize:(double)maxCompressedImageSize callback:(void (^)(UIImage *image,NSData *compressedData,MLURL *url))callback
{
    
    void (^block)() = ^{
        MLKitSelectPictureTask *task = [MLKitSelectPictureTask new];
        task.maxCompressedImageSize = maxCompressedImageSize;
        task.compressedImageBlock = callback;
        task.allowsEditing = allowEditing;
        task.directReturnOriginalImage = directReturnOriginalImage;
        [task selectPictureWithSourceType:sourceType];
        
        [self.selectPictureTasks addObject:task];
    };
    
    //相册的权限在VC被present后系统自己会提示
    if (sourceType != UIImagePickerControllerSourceTypeCamera) {
        block();
        return;
    }
    
    //检测相机权限
    NSString *mediaType = AVMediaTypeVideo;
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:mediaType];
    NSString *tips = @"请在设备的\"设置-隐私-相机\"中允许访问相机。";
    
    if(authStatus == AVAuthorizationStatusRestricted){
        SHOW_SIMPLE_TIPS(@"您的设备似乎不支持相机");
    }else if (authStatus == AVAuthorizationStatusDenied){
        SHOW_SIMPLE_TIPS(tips);
    }else if (authStatus == AVAuthorizationStatusAuthorized){
        block();
    }else if (authStatus == AVAuthorizationStatusNotDetermined){
        //TODO: 良好的设计可以先alert提示一下，然后点了确定之后再requestAccessForMediaType
        [AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if(granted){//点击允许访问时调用
                    block();
                }else {
                    SHOW_SIMPLE_TIPS(tips);
                }
            });
        }];
    }else{
        //其他的不知道是什么鬼东西，直接性的继续吧
        block();
    }
}

#pragma mark - actionsheet
+ (UIActionSheet*)commonActionSheetForSelectPictureWithDelegate:(id<UIActionSheetDelegate>)delegate
{
    return [MLKitManager commonActionSheetForSelectPictureWithDelegate:delegate title:nil];
}

+ (UIActionSheet*)commonActionSheetForSelectPictureWithDelegate:(id<UIActionSheetDelegate>)delegate title:(NSString*)title
{
    UIActionSheet *actionSheet = nil;
    BOOL library = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary];
    BOOL camera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    if (library&&!camera) {
        actionSheet = [[UIActionSheet alloc]initWithTitle:title delegate:delegate cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"使用手机相册",nil];
    }else if (camera&&!library){
        actionSheet = [[UIActionSheet alloc]initWithTitle:title delegate:delegate cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"使用摄像头拍照",nil];
    }else if (camera&&library){
        actionSheet = [[UIActionSheet alloc]initWithTitle:title delegate:delegate cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"使用手机相册",@"使用摄像头拍照",nil];
    }else{
        [[[UIAlertView alloc]initWithTitle:title message:@"你的设备不可选择图像或拍照" delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:nil, nil]show];
        return nil;
    }
    
    return actionSheet;
}

@end


@implementation MLKitSelectPictureTask

- (void)selectPictureWithSourceType:(UIImagePickerControllerSourceType)sourceType
{
    UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
    imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage];
    imagePickerController.sourceType = sourceType;
    imagePickerController.allowsEditing = self.allowsEditing;
    imagePickerController.delegate = self;
    
    UIViewController *vc = APPDELEGATE.window.rootViewController;
    while (vc.presentedViewController) {
        vc = vc.presentedViewController;
    }
    [vc presentViewController:imagePickerController animated:YES completion:nil];
}

#pragma mark - UIImagePickerControllerDelegate
#define kCompressedSelectImageDir @"MLKitCompressedSelectImageDir"
+ (MLURL*)compressionImagePathWithKey:(NSString*)key
{
    NSSearchPathDirectory searchDir = NSDocumentDirectory;
    NSSearchPathDomainMask searchMask = NSUserDomainMask;
    
    //这里检测是否存在此文件夹，不存在就建立
    NSArray *paths = NSSearchPathForDirectoriesInDomains(searchDir, searchMask, YES);
    NSString *dir = [[paths firstObject] stringByAppendingPathComponent:kCompressedSelectImageDir];
    
    if (![[NSFileManager defaultManager] fileExistsAtPath:dir]){
        if([[NSFileManager defaultManager] createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:NULL]){
            //添加不备份标记
            [[NSFileManager defaultManager]addSkipBackupAttributeToItemAtPath:dir];
        }
    }
    
    //设置一个新文件名字
    MLURL *url = [MLURL fileURLWithPath:[kCompressedSelectImageDir stringByAppendingPathComponent:key] isDirectory:NO searchPathDirectory:searchDir searchPathDomainMask:searchMask];
    
    return url;
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    @autoreleasepool {
        UIImage *image = nil;
        if (self.allowsEditing) {
            image = [info valueForKey:UIImagePickerControllerEditedImage];
        }else{
            image = [info valueForKey:UIImagePickerControllerOriginalImage];
        }
        if (image) {
            image = [image fixOrientation];
            if (self.directReturnOriginalImage) {
                if (self.compressedImageBlock) {
                    self.compressedImageBlock(image,nil,nil);
                }
                
                [picker dismissViewControllerAnimated:YES completion:nil];
                [[MLKitManager manager].selectPictureTasks removeObject:self];
                return;
            }
            
            MLProgressHUD *mbp = SHOW_HUD(picker.view.window);
            mbp.detailsLabelText = @"正在处理中...";
            mbp.detailsLabelFont = [UIFont boldSystemFontOfSize:14.0f];
            
            void(^completeBlock)(NSData *) = ^(NSData *compressedData){
                //用当前时间做文件名
                time_t curUnixTime = 0;
                time(&curUnixTime);
                NSString *key = [NSString stringWithFormat:@"%ld-%@.jpg", curUnixTime,[MLSecurity md5Data:compressedData]];
                MLURL *url = [MLKitSelectPictureTask compressionImagePathWithKey:key];
                
                if ([compressedData writeToFile:[url path] atomically:YES])
                {
                    if (self.compressedImageBlock) {
                        self.compressedImageBlock([UIImage imageWithData:compressedData],compressedData,url);
                    }
                }else{
                    SHOW_SIMPLE_TIPS(@"图片写入失败，请重试");
                }
                
                HIDE_HUD(picker.view.window);
                
                [picker dismissViewControllerAnimated:YES completion:nil];
                [[MLKitManager manager].selectPictureTasks removeObject:self];
            };
            
            NSInteger maxCompressedImageSize = self.maxCompressedImageSize;
            if (maxCompressedImageSize<=0) maxCompressedImageSize = 1024*1000;//必须得有个最大限制1MB
            
            //压缩至IM_PICTURE_MAX_LENGTH
            [image dataFoCompressImageToMaxDataLength:maxCompressedImageSize maxSideLength:1280 withCallback:^(UIImage *originalImage, NSData *compressedData) {
                completeBlock(compressedData);
            }];
        }else{
            [picker dismissViewControllerAnimated:YES completion:nil];
            [[MLKitManager manager].selectPictureTasks removeObject:self];
        }
    }
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [picker dismissViewControllerAnimated:YES completion:nil];
    
    [[MLKitManager manager].selectPictureTasks removeObject:self];
}

@end
